#include "stdafx.h"
#include "Alchemy.h"

#include "Item.h"
#include "EventCodes.h"
#include "EventManagerSngl.h"
#include "../db/Alchemy.h"

#ifdef WIN32
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#endif

namespace serika
{
	namespace dq
	{
		Alchemy::Alchemy(db::Alchemy* alchemy, TransientState::Enum state)
			: mProduct(0)
			, mMaterial1(0)
			, mMaterial2(0)
			, mMaterial3(0)
		{
			mDb = new Db(alchemy, state);
		}

		Alchemy::~Alchemy()
		{
			delete mDb;
		}

		// static
		Alchemy* Alchemy::FromDb(db::Alchemy* alchemy)
		{
			return new Alchemy(alchemy, TransientState::Clean);
		}

		int Alchemy::Product() const
		{
			return mDb->GetInt("product");
		}

		int Alchemy::Material1() const
		{
			return mDb->GetInt("material1");
		}

		int Alchemy::Num1() const
		{
			return mDb->GetInt("num1");
		}

		int Alchemy::Material2() const
		{
			return mDb->GetInt("material2");
		}

		int Alchemy::Num2() const
		{
			return mDb->GetInt("num2");
		}

		int Alchemy::Material3() const
		{
			return mDb->GetInt("material3");
		}

		int Alchemy::Num3() const
		{
			return mDb->GetInt("num3");
		}

		Item* Alchemy::ProductItem()
		{
			int productId = this->Product();
			if (0 == productId)
			{
				return 0;
			}

			if (!mProduct)
			{
				this->SendEvent(productId, PEC::RequestProduct);
			}

			return mProduct;
		}

		Item* Alchemy::Material1Item()
		{
			int mat1 = this->Material1();
			if (0 == mat1)
			{
				return 0;
			}

			if (!mMaterial1)
			{
				this->SendEvent(mat1, PEC::RequestMaterial1);
			}

			return mMaterial1;
		}

		Item* Alchemy::Material2Item()
		{
			int mat2 = this->Material2();
			if (0 == mat2)
			{
				return 0;
			}

			if (!mMaterial2)
			{
				this->SendEvent(mat2, PEC::RequestMaterial2);
			}

			return mMaterial2;
		}

		Item* Alchemy::Material3Item()
		{
			int mat3 = this->Material3();
			if (0 == mat3)
			{
				return 0;
			}

			if (!mMaterial3)
			{
				this->SendEvent(mat3, PEC::RequestMaterial3);
			}

			return mMaterial3;
		}

		inline void Alchemy::SendEvent(int id, int code)
		{
			ut::Event* e = ut::Event::NewEvent(EventType::Persistence, code);
			e->SetSource(id);
			EventManager::AttachLogicEventHandler(this);
			EventManager::SendEvent(e);
			EventManager::DetachLogicEventHandler(this);
		}

		void Alchemy::Handle(const ut::Event& e)
		{
			switch (e.GetCode())
			{
			case LEC::ProductItem:
				mProduct = e.GetUserData<Item>();
				break;

			case LEC::Material1Item:
				mMaterial1 = e.GetUserData<Item>();
				break;

			case LEC::Material2Item:
				mMaterial2 = e.GetUserData<Item>();
				break;

			case LEC::Material3Item:
				mMaterial3 = e.GetUserData<Item>();
				break;
			}
		}
	}
}
